package sessionBeans;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.xml.ws.BindingProvider;

import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;

import org.jboss.logging.Logger;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.sun.org.apache.xalan.internal.xsltc.compiler.Parser;

import entities.Modulo;
import entities.OrdenDespacho;
import entities.ServiciosModulo;
import estadoEntregaDespachoPortalService.ServidorEstadoEntregaBean;
import estadoEntregaDespachoPortalService.ServidorEstadoEntregaBeanService;
import services.AdministrarDespachoBean;
import xml.RespuestaXML;

/**
 * Session Bean implementation class AdministradorMensajeriaBean
 */
@Stateless
@LocalBean
public class AdministradorMensajeriaBean implements AdministradorMensajeria {

	private static final String DEFAULT_CONNECTION_FACTORY = "jms/RemoteConnectionFactory";
    //private static final String DEFAULT_USERNAME = "deposito";
    //private static final String DEFAULT_PASSWORD = "deposito.1234";
    private static final String INITIAL_CONTEXT_FACTORY = "org.jboss.naming.remote.client.InitialContextFactory";
    /**
     * Default constructor. 
     */
    
    Logger logger = Logger.getLogger(AdministrarDespachoBean.class);
    
    @EJB
    private AdministradorModulo adminModulo;
    
    public AdministradorMensajeriaBean() {
        // TODO Auto-generated constructor stub
    }

	@Override
	public boolean EnviarSolicitudADepositoSinAutenticacion(String solicitudXML, int modulo) {
		// TODO Auto-generated method stub
		Modulo mod = adminModulo.buscarModulo(modulo);
    	ServiciosModulo serMod = adminModulo.buscarServicio(1, modulo);
    	if(serMod == null)
    	{
    		Date fecha = Calendar.getInstance().getTime();
			logger.error("ERROR: Error enviando el mensaje a Deposito (/n) No existe el servicio indicado: " +"(/n) FECHA: "+fecha);
			return false;
    	}
    	
    	String PROVIDER_URL = "remote://" + mod.getIp() + ":4447";
    	String DEFAULT_DESTINATION = serMod.getPath();
    	ConnectionFactory connectionFactory = null;
        Connection connection = null;
        Session session = null;
        MessageProducer producer = null;
        Destination destination = null;
        Context context = null;

            // Set up the context for the JNDI lookup
            final Properties env = new Properties();
            env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
            env.put(Context.PROVIDER_URL, System.getProperty(Context.PROVIDER_URL, PROVIDER_URL));
            //env.put(Context.SECURITY_PRINCIPAL, System.getProperty("username", DEFAULT_USERNAME));
            //env.put(Context.SECURITY_CREDENTIALS, System.getProperty("password", DEFAULT_PASSWORD));
            try {
				context = new InitialContext(env);
				// Perform the JNDI lookups
	            String connectionFactoryString = System.getProperty("connection.factory", DEFAULT_CONNECTION_FACTORY);
	            connectionFactory = (ConnectionFactory) context.lookup(connectionFactoryString);

	            String destinationString = System.getProperty("destination", DEFAULT_DESTINATION);
	            destination = (Destination) context.lookup(destinationString);

	            // Create the JMS connection, session, producer, and consumer
	            //connection = connectionFactory.createConnection(System.getProperty("username", DEFAULT_USERNAME), System.getProperty("password", DEFAULT_PASSWORD));
	            connection = connectionFactory.createConnection();
	            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
	            producer = session.createProducer(destination);
	            connection.start();
			// crear un mensaje de tipo text y setearle el contenido
			TextMessage message = session.createTextMessage();
			message.setText(solicitudXML);
			// enviar el mensaje
			producer.send(message);
			 connection.close();
			 return true;
			} catch (NamingException | JMSException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				Date fecha = Calendar.getInstance().getTime();
				logger.error("ERROR: Error enviando el mensaje a Deposito (/n) EXCEPTION: "+ e.getStackTrace() +"(/n) FECHA: "+fecha);
			}
            return false;
	}

	@Override
	public void ConfirmarOrdenDeDespachoADespachar(OrdenDespacho orden) {
		// TODO Auto-generated method stub
	
		try {
			String url;
			String ipPortal = orden.getPortal().getIp();
			String webService = this.adminModulo.buscarServicio(3, orden.getPortal().getId()).getPath();
			url = "http://" + ipPortal + webService;
			ServidorEstadoEntregaBeanService cliente = new ServidorEstadoEntregaBeanService();			
			ServidorEstadoEntregaBean puerto = cliente.getServidorEstadoEntregaBeanPort();
			BindingProvider bp = (BindingProvider)puerto;
			bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, url);
			puerto.notificarEntregaDespacho(Integer.parseInt(orden.getCodigoOrdenCompra()));
			
		} catch (Exception e) {
			// TODO: handle exception
			logger.error("ERROR: Error enviando la confirmaicon de Orden de despacho a Portal (/n) EXCEPTION: "+ e.getStackTrace().toString() +"(/n) FECHA: "+ Calendar.getInstance().getTime());
		}
		
		
		List<Modulo> logisticas = this.adminModulo.buscarTipoModulos("Monitoreo") ;
		Modulo logActivo = null;
		
		for (Modulo modulo : logisticas) {
		if(modulo.isActivo())
		{
			logActivo = modulo;
			break;
		}
		}
		
		String url;
		String ipLog = logActivo.getIp();
		String rest = this.adminModulo.buscarServicio(2, logActivo.getId()).getPath();
		url = "http://" +ipLog + rest + "/" + orden.getCodigo();
		
		this.EnviarConfirmacionOrdenALogistica(url);
		
		
	}
	
	private String EnviarConfirmacionOrdenALogistica(String urlStr) {
		String mensaje = null;
		
		try {
			URL	url = new URL(urlStr);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("POST");
			if(conn.getResponseCode()!=200){
				logger.error("ERROR: Error enviando la confirmaicon de Orden de despacho a Logistica (/n) EXCEPTION: "+ conn.getResponseMessage() +"(/n) FECHA: "+ Calendar.getInstance().getTime());
				return null;
			}
			BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			StringBuilder sb = new StringBuilder();
			String line;
			while((line = rd.readLine()) != null){
				sb.append(line);
			}
			
			
			rd.close();
			conn.disconnect();
			
			ObjectMapper obMapper = new ObjectMapper();
			RespuestaXML resp = obMapper.readValue(sb.toString(), RespuestaXML.class);
			
			
			if(resp.getEstado().equals("ERROR"))
			{
				logger.error("ERROR: Error enviando la confirmaicon de Orden de despacho a Logistica (/n) EXCEPTION: "+ mensaje +"(/n) FECHA: "+ Calendar.getInstance().getTime());
			}
			
			mensaje = resp.getMensaje();
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			logger.error("ERROR: Error enviando la confirmaicon de Orden de despacho a Logistica (/n) EXCEPTION: "+ e.getMessage() +"(/n) FECHA: "+ Calendar.getInstance().getTime());
			e.printStackTrace();
		} catch (Exception e) {
			// TODO: handle exception
			logger.error("ERROR: Error enviando la confirmaicon de Orden de despacho a Logistica (/n) EXCEPTION: "+ e.getMessage() +"(/n) FECHA: "+ Calendar.getInstance().getTime());
			e.printStackTrace();
		}
		
		System.out.println(mensaje);
		return mensaje;
	}

	@Override
	public boolean EnviarSolicitudADepositoConAutenticacion(String solicitudXML,
			int modulo) {
		// TODO Auto-generated method stub
		Modulo mod = adminModulo.buscarModulo(modulo);
    	ServiciosModulo serMod = adminModulo.buscarServicio(1, modulo);
    	if(serMod == null)
    	{
    		Date fecha = Calendar.getInstance().getTime();
			logger.error("ERROR: Error enviando el mensaje a Deposito (/n) No existe el servicio indicado: " +"(/n) FECHA: "+fecha);
			return false;
    	}
    	
    	String PROVIDER_URL = mod.getIp();
    	String DEFAULT_DESTINATION = serMod.getPath();
    	ConnectionFactory connectionFactory = null;
        Connection connection = null;
        Session session = null;
        MessageProducer producer = null;
        Destination destination = null;
        Context context = null;

            // Set up the context for the JNDI lookup
            final Properties env = new Properties();
            env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
            env.put(Context.PROVIDER_URL, System.getProperty(Context.PROVIDER_URL, PROVIDER_URL));
            env.put(Context.SECURITY_PRINCIPAL, System.getProperty("username", "deposito"));
            env.put(Context.SECURITY_CREDENTIALS, System.getProperty("password", "deposito.1234"));
            try {
				context = new InitialContext(env);
				// Perform the JNDI lookups
	            String connectionFactoryString = System.getProperty("connection.factory", DEFAULT_CONNECTION_FACTORY);
	            connectionFactory = (ConnectionFactory) context.lookup(connectionFactoryString);

	            String destinationString = System.getProperty("destination", DEFAULT_DESTINATION);
	            destination = (Destination) context.lookup(destinationString);

	            // Create the JMS connection, session, producer, and consumer
	            connection = connectionFactory.createConnection(System.getProperty("username", "deposito"), System.getProperty("password", "deposito.1234"));
	            
	            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
	            producer = session.createProducer(destination);
	            connection.start();
			// crear un mensaje de tipo text y setearle el contenido
			TextMessage message = session.createTextMessage();
			message.setText(solicitudXML);
			// enviar el mensaje
			producer.send(message);
			 connection.close();
			 return true;
			} catch (NamingException | JMSException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				Date fecha = Calendar.getInstance().getTime();
				logger.error("ERROR: Error enviando el mensaje a Deposito (/n) EXCEPTION: "+ e.getStackTrace() +"(/n) FECHA: "+fecha);
			}
		return false;
	}

}
